//
//  FuckPod.hpp
//  fuckpod
//
//  Created by 李贺 on 2022/1/11.
//https://cloud.tencent.com/developer/article/1176216

#ifndef FuckPod_hpp
#define FuckPod_hpp

#include <stdio.h>
#include <string>
#include <iostream>
#include <getopt.h>
#include <cstdlib>
#include <array>
#include <tuple>

/*
 extern char* optarg：保存选项的参数；
 extern int optind：记录下一个检索位置；
 extern int opterr：初始值为1
    如果在处理期间遇到了不符合optstring指定的其他选项，
    getopt()将显示一个错误消息，
    并将全局变量optopt设为”?”字符。
    opterr决定是否将错误信息输出到stderr，为0时表示不输出；其他值表示输出
 extern int optopt：
 存放不在选项字符串optstring中的选项。

 */

/**
"ho:w::"
1:字符后面有: 表示必须有参
2: 字符后面:: 表示参数为可选参数
3: 字符后面没有参数,表示该选项不支持参数
*/

using namespace::std;

class fuckpod {

public:
    
    void print_usage() {
        cout << "****  usage  ****" << endl;
        cout << "-h or --help, help message" << endl;
        cout << "-wy or --what=y, what just test" << endl;
        cout << "-o y or -oy or --open=y or --open y, open project" << endl;
        cout << "**** welcome ****" << endl;
    }
    
    void need_what() {
        if (string(optarg) == "y") {
            cout << "you need what" << endl;
        } else {
            cout << "you do not need what" << endl;
        }
    }
    
    void remove_pod_podlock() {
        cout << "is removing Pods and Podfile.lock" << endl;
        system("rm -rf ./Pods");
        system("rm -rf ./Podfile.lock");
        cout << "remove Pods add Podfile.lock success" << endl;
    }
    
    tuple<int,string> my_popen(string command) {
        
        tuple<int,string> tu = make_tuple(-1,"error");

        std::array<char, 128> buffer;
        std::string result;

        std::cout << "Opening reading pipe" << std::endl;
        FILE* pipe = popen(command.c_str(), "r");
        if (!pipe)
        {
            std::cerr << "Couldn't start command." << std::endl;
            get<1>(tu) = "Couldn't start command.";
            return tu;
        }
        while (fgets(buffer.data(), 128, pipe) != NULL) {
            std::cout << "Reading..." << std::endl;
            result += buffer.data();
        }
        auto returnCode = pclose(pipe);

        std::cout << result << std::endl;
        std::cout << returnCode << std::endl;
        get<0>(tu) = returnCode;
        get<1>(tu) = result;
        return tu;
    }
    
    void open_project() {
        cout << "have option -o" << endl;
        cout << "the argument of -o is" << optarg << endl;
        if (string(optarg) == "y") {
            tuple<int, string> tu = my_popen("ls -d *.xcworkspace");
            cout << "open the project" << endl;
            cout << get<1>(tu) << endl;
            string cmd = "open ";
            cmd.append(get<1>(tu));
            system(cmd.c_str());
        } else {
            tuple<int, string> tu = my_popen("ls -d *.xcworkspace");
            cout << "open the project" << endl;
            cout << get<1>(tu) << endl;
        }
    }
    
    void pod_update() {
        string cmd_str = "pod update --verbose --no-repo-update --clean-install";
        cout << cmd_str << endl;
        int ret = system(cmd_str.c_str());
        if (ret != 0) {
            cout << "pod update error" << endl;
            exit(-1);
        }
    }
    
    int deal_option(int argc,char * const *argv) {
        
        int t_opt;
        int t_option_index = 0;
    
        const char * short_options = (char*) "ho:w::";
        
        static struct option long_options[] = {
                {"help", no_argument, NULL, 'h'},
                {"what", optional_argument, NULL, 'w'},
                {"open", required_argument, NULL, 'o'},
                {0, 0, 0, 0}
        };
        
        while ((t_opt = getopt_long(argc, argv, short_options, long_options, &t_option_index)) != -1 ) {
            switch (t_opt) {
                case '?':
                case 'h':
                    print_usage();
                    break;
                case 'w':
                    this->need_what();
                    this->remove_pod_podlock();
                    this->pod_update();
                    this->open_project();
                    break;
                case 'o':
                    this->remove_pod_podlock();
                    this->pod_update();
                    this->open_project();
                    break;
                default:
                    print_usage();
                    break;
            }
        }
        cout << "over" << endl;
        return 0;
    }
    
};

#endif /* FuckPod_hpp */
